<?php
namespace Console\Config;

use Phalcon\Cache\Backend\Libmemcached as PhalconMemcached;
use Phalcon\Cache\Backend\Redis;
use Phalcon\Cache\Frontend\Data as FrontendData;
use Phalcon\Cli\Console;
use Phalcon\Config;
use Phalcon\Db\Adapter\Pdo\Mysql as DbAdapter;
use Phalcon\Db\Profiler;
use Phalcon\Di\FactoryDefault\Cli;
use Phalcon\Events\Manager as EventsManager;
use Phalcon\Exception;
use Phalcon\Loader;
use Phalcon\Logger\Adapter\File as LoggerAdapterFile;
use Phalcon\Logger\Formatter\Line as LineFormatter;

class Bootstrap
{
    private $console;

    public function __construct($envConfig)
    {
        $di         = new Cli();
        $commonsDir = dirname(APP_PATH) . '/Commons';
        $tasksDir   = APP_PATH . DIRECTORY_SEPARATOR . 'Tasks';
        $config     = (new Config($envConfig))->merge(include $commonsDir . '/Config/Base.php');
        $loader     = new Loader();
        $loader->registerDirs([
            $tasksDir,
            $commonsDir
        ]);
        $loader->registerNamespaces([
            'Commons' => $commonsDir,
            'Console' => APP_PATH
        ]);
        $loader->registerFiles([$config->application->vendorAutoLoader]);
        $loader->register();

        $di->set('globalConfig', function () use ($config)
        {
            return $config;
        }, true);
        $di->set('logger', function () use ($config)
        {
            $logger = new LoggerAdapterFile(dirname(__DIR__) . '/Logs/' . date('Ymd') . '.log');
            $logger->setFormatter(new LineFormatter('[%date%][%type%] [%message%]', 'Y-m-d H:i:s'));
            return $logger;
        }, true);
        $di->set('db', function () use ($config)
        {
            $db = new DbAdapter([
                'host'     => $config->database->host,
                'username' => $config->database->username,
                'password' => $config->database->password,
                'dbname'   => $config->database->dbname,
                'charset'  => 'utf8mb4',
                'options'  => [
                    \PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8mb4',
                    \PDO::ATTR_EMULATE_PREPARES   => false,
                    \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
                    \PDO::ATTR_PERSISTENT         => true
                ]
            ]);
            //测试环境建立一个事件监听
            if (defined('ENVIRONMENT') && ENVIRONMENT == 'development') {
                $eventsManager = new EventsManager();
                //$profiler      = $di->getShared('profiler');
                $profiler = new Profiler();
                $eventsManager->attach('db', function ($event, $connection) use ($profiler)
                {
                    if ($event->getType() == 'beforeQuery') {
                        $profiler->startProfile($connection->getSQLStatement());
                    }
                    if ($event->getType() == 'afterQuery') {
                        $profiler->stopProfile();
                    }
                });
                $db->setEventsManager($eventsManager);
            }
            return $db;
        });
        $di->set('memCache', function () use ($config)
        {
            $frontCache = new FrontendData([
                'lifetime' => 86400,
            ]);
            return new PhalconMemcached($frontCache, [
                'servers' => [
                    [
                        'host'   => $config->memcached->host,
                        'port'   => $config->memcached->port,
                        'weight' => 1
                    ]
                ],
                'client'  => [
                    \Memcached::OPT_HASH       => \Memcached::HASH_MD5,
                    \Memcached::OPT_PREFIX_KEY => $config->memcached->prefix,
                ]
            ]);
        }, true);

        $di->set('redis', function () use ($config)
        {
            $frontCache = new FrontendData([
                'lifetime' => 86400,
            ]);
            $redisCache = new Redis($frontCache, [
                'host'       => $config->redis->host,
                'port'       => $config->redis->port,
                'persistent' => false,
                'prefix'     => $config->redis->prefix,
            ]);
            return $redisCache;
        }, true);

        $this->console = new Console();
        $this->console->setDI($di);
    }

    public function run($argv, $module = 'Tasks')
    {
        $arguments = [];
        foreach ($argv as $k => $arg) {
            if ($k == 1) {
                $arguments['task'] = 'Console\\' . ucfirst($module) . '\\' . ucfirst(str_replace('/', '\\', $arg));
            } else {
                if ($k == 2) {
                    $arguments['action'] = $arg;
                } else {
                    if ($k >= 3) {
                        $arguments['params'][] = $arg;
                    }
                }
            }
        }

        define('CURRENT_TASK', (isset($argv[1]) ? $argv[1] : null));
        define('CURRENT_ACTION', (isset($argv[2]) ? $argv[2] : null));

        try {
            //处理参数
            $this->console->handle($arguments);
        } catch (Exception $ex) {
            echo $ex->getMessage();
            exit(255);
        }
    }
}
